package com.jjc.MyWebApp.Plugin;

import com.jfinal.aop.Enhancer;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jjc.MyWebApp.Annotation.Service;
import com.jjc.MyWebApp.Service.BaseService;
import com.jjc.MyWebApp.kit.ClassScanKit;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by jiaji on 2017/5/11.
 */
public class ServicePlugin implements IPlugin {
    private static final Log log = Log.getLog(ServicePlugin.class);
    /**
     * service实例
     */
    private static final Map<String, BaseService> serviceMap = new HashMap<String, BaseService>();

    /**
     * 获取指定Service实例
     *
     * @param ServiceName
     * @return
     */
    public static BaseService getService(String ServiceName) {
        return serviceMap.get(ServiceName);
    }

    public boolean start() {
        // 扫描所有继承BaseService的类
        Set<Class<?>> serviceClasss = ClassScanKit.searchByClassLoader(BaseService.class);
        //循环处理Service实例化
        for (Class serviceClass : serviceClasss) {
            Service serviceBind = (Service) serviceClass.getAnnotation(Service.class);
            if (serviceBind == null) {
                if (log.isWarnEnabled()) log.warn(serviceClass.getName() + "继承了BaseService，但是没有注解绑定 ！！！");
                throw new RuntimeException(serviceClass.getName() + "继承了BaseService，但是没有注解绑定 ！！！");
            }
            // 获取Service注解属性
            String name = serviceBind.value().trim();
            if (StrKit.isBlank(name)) {
                if (log.isErrorEnabled()) log.error(serviceClass.getName() + "注解错误，name不能为空 ！！！");
                throw new RuntimeException(serviceClass.getName() + "注解错误，name不能为空 ！！！");
            }

            if (getService(name) == null) {
                BaseService baseService = null;
                if (serviceBind.tx()) {
                    baseService = (BaseService) Enhancer.enhance(serviceClass, Tx.class);
                } else {
                    try {
                        baseService = (BaseService) serviceClass.newInstance();
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                serviceMap.put(name,baseService);
                if(log.isDebugEnabled()) log.debug("Service注册： name = " + name + ", class = " + serviceClass.getName());
            }else{
                if(log.isErrorEnabled()) log.error(serviceClass.getName() + "注解错误，Service name重复注册 ！！！");
                throw new RuntimeException(serviceClass.getName() + "注解错误，Service name重复注册 ！！！");
            }

        }

        //处理Service相互注入
        for (Class serviceClass : serviceClasss){
            //获取注解对象
            Service serviceBind = (Service) serviceClass.getAnnotation(Service.class);

            //查找成员变量
            Field[] Fields=serviceClass.getDeclaredFields();
            for(Field field :Fields){
                field.setAccessible(true);
                //判断成员变量类型
                if (BaseService.class.isAssignableFrom(field.getType())){
                    try {
                        field.set(getService(serviceBind.value()),getService(field.getName()));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }finally {
                        field.setAccessible(false);
                    }
                }
            }
        }
        return true;
    }

    public boolean stop() {
        return true;
    }
}
